﻿using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Ops.Mpc.Controllers;
using Ops.Mpc.Presenters;

namespace Ops.Mpc.States
{
    public class StateActionButton : Button
    {
        private static readonly DependencyProperty CurrentStateProperty = DependencyProperty.Register("CurrentState", typeof(IState), typeof(StateActionButton), new PropertyMetadata(new PropertyChangedCallback(OnCurrentStateChanged)));
        private static readonly DependencyProperty IsStateActionAvailableProperty = DependencyProperty.Register("IsStateActionAvailable", typeof(bool), typeof(StateActionButton), new PropertyMetadata(new PropertyChangedCallback(OnIsStateActionAvailableChanged)));
        public static readonly DependencyProperty StateActionItemNameProperty = DependencyProperty.Register("StateActionItemName", typeof(string), typeof(StateActionButton), null);
        public static readonly DependencyProperty PresenterNameProperty = DependencyProperty.Register("PresenterName", typeof(string), typeof(StateActionButton), null);

        public string StateActionItemName
        {
            get
            {
                return (string)this.GetValue(StateActionItemNameProperty);
            }

            set
            {
                this.SetValue(StateActionItemNameProperty, value);
            }

        }

        public string PresenterName
        {
            get
            {
                return (string)this.GetValue(PresenterNameProperty);
            }

            set
            {
                this.SetValue(PresenterNameProperty, value);
            }

        }

        public StateActionButton()
        {
            this.IsEnabled = false;
            this.Loaded += new RoutedEventHandler(OnLoaded);
        }
        
        protected void OnLoaded(object sender, RoutedEventArgs e)
        {
            IController iController = this.GetController();

            if (iController != null)
            {
                Debug.WriteLine("Setting controller binding for state action button {0}", this.Name);
                this.SetBinding(CurrentStateProperty, new Binding("CurrentState") { Source = iController });
            }
        }

        protected override void OnClick()
        {
            base.OnClick();
            Debug.WriteLine("Click for state action button {0}", this.Name);
            IStateAction iStateAction = this.GetStateAction();


            if(iStateAction != null)
                iStateAction.Execute(this.DataContext, new ActionResultCallback(new ActionResultCallback(OnStateActionComplete)));
            

        }

        private void OnStateActionComplete(ActionResult actionResult)
        {

        }

        protected Presenter GetPresenter()
        {
            if (string.IsNullOrEmpty(this.PresenterName))
                return Presenter.GetParentPresenter(this);
            else
               return this.FindName(this.PresenterName) as Presenter;
        }

        protected IController GetController()
        {
            Presenter presenter = this.GetPresenter();;

            if (presenter != null)
                return presenter.Controller;
            else
                return null;
        }

        protected IState GetCurrentState()
        {
            IController iController = this.GetController();

            if (iController != null)
                return iController.CurrentState;
            else
                return null;
        }

        protected IStateAction GetStateAction()
        {
            IState iState = this.GetCurrentState();

            if (iState != null)
                return iState.GetStateAction(this.StateActionItemName,true);
            else
                return null;
        }


        private static void OnCurrentStateChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            StateActionButton stateActionButton = dependencyObject as StateActionButton;
            IState iState = dependencyPropertyChangedEventArgs.NewValue as IState;
            Debug.WriteLine("Current state changed for state action button {0}", stateActionButton.Name);

            if (iState != null)
            {
                IStateAction iStateAction = stateActionButton.GetStateAction();

                if (iStateAction != null)
                {
                    Debug.WriteLine("Found action {0} for action button {1}", iStateAction.ItemName, stateActionButton.Name);
                    stateActionButton.SetBinding(IsStateActionAvailableProperty, new Binding("IsAvailable") { Source = iStateAction });
                }
                else
                {
                    Debug.WriteLine("No action {0} for state action button {1} found", stateActionButton.StateActionItemName, stateActionButton.Name);
                    stateActionButton.SetValue(IsStateActionAvailableProperty, false);
                }
            }
            else
            {
                Debug.WriteLine("No state found for state action button {0}", stateActionButton.Name);

                stateActionButton.SetValue(IsStateActionAvailableProperty, false);
            }
        }

        private static void OnIsStateActionAvailableChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            StateActionButton stateActionButton = dependencyObject as StateActionButton;

            if(stateActionButton.GetStateAction() != null && ((bool)dependencyPropertyChangedEventArgs.NewValue) == true )
                stateActionButton.IsEnabled = true;
            else
                stateActionButton.IsEnabled = false;

            Debug.WriteLine("State action button {0} IsEnabled = {1}", stateActionButton.Name,stateActionButton.IsEnabled);

        }


    }
}
